package org.durandj.ystream.client.network;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.security.InvalidParameterException;
import java.util.logging.Logger;

/**
 * Handles the work of translating a message into
 * a data stream and then sending it through the
 * requested socket.
 * 
 * @author durandj
 * @version 1.0
 *
 */
public class PacketSender
{
	/**
	 * Logs events from the packet sender.
	 */
	private static final Logger log = Logger.getLogger(PacketSender.class.getName());
	
	/**
	 * The socket to send data through.
	 */
	private Socket socket;
	
	/**
	 * Creates a packet sender for sending packets to a particular socket.
	 * 
	 * @param socket - the target socket
	 */
	public PacketSender(Socket socket)
	{
		if(socket == null)
			throw new NullPointerException("Must give a valid socket.");
		
		if(!socket.isConnected())
			throw new InvalidParameterException("Must give a connected socket.");
		
		this.socket = socket;
	}
	
	public void sendPacket(Packet packet)
	{
		if(packet == null)
			throw new NullPointerException("Must give a valid packet.");
		
		try
		{
			// We need to get a data stream writer and a temporary buffer for the data.
			DataOutputStream writer = new DataOutputStream(socket.getOutputStream());
			ByteBuffer buf = ByteBuffer.allocate(Packet.MAX_PACKET_SIZE);
			
			// First we store the opcode in the buffer.
			buf.putInt(packet.getOpcode());
			
			// We need to change the priority into a numeric value so let's do that quick.
			int nPriority = -1;
			switch(packet.getPriority())
			{
			case LOW:
				nPriority = 0;
				break;
				
			case MEDIUM:
				nPriority = 1;
				break;
				
			case HIGH:
				nPriority = 2;
				break;
			}
			
			// We can now write the priority to the packet.
			buf.putInt(nPriority);
			
			// Store the packet contents in the buffer.
			buf.putInt(packet.getSize());
			buf.put(packet.getContents());
			
			buf.rewind();
			
			// We can now write the buffered data to the stream!
			writer.write(buf.array());
		}
		catch(IOException e)
		{
			log.warning("Unable to send packet to the server!");
		}
	}
}
